package com.gwcm.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gwcm.config.AlipayConfig;
import com.gwcm.exception.BusinessException;
import com.gwcm.mapper.*;
import com.gwcm.model.dto.alipay.AlipayPayNotify;
import com.gwcm.model.dto.memberCard.MemberCardQueryRequest;
import com.gwcm.model.dto.orderInfo.CardOrderInfoQueryRequest;
import com.gwcm.model.entity.*;
import com.gwcm.model.enums.AlipayTradeStatus;
import com.gwcm.model.enums.PaymentTypeEnum;
import com.gwcm.model.enums.TradeStateEnum;
import com.gwcm.model.vo.CardOrderInfoVo;
import com.gwcm.model.vo.ProductVo;
import com.gwcm.service.CardOrderInfoService;
import com.gwcm.util.PageUtil;
import com.yhz.commonutil.common.ErrorCode;
import com.yhz.commonutil.constant.SortConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
* @author 15375
* @description 针对表【card_order_info(会员卡订单表)】的数据库操作Service实现
* @createDate 2023-03-21 16:19:38
*/
@Service
@Slf4j
public class CardOrderInfoServiceImpl extends ServiceImpl<CardOrderInfoMapper, CardOrderInfo>
    implements CardOrderInfoService{
    @Resource
    private CardOrderInfoMapper cardOrderInfoMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private MemberCardMapper memberCardMapper;
    @Resource
    private AlipayConfig alipayConfig;

    /**
     * 会员卡订单分页查询
     * @param cardOrderInfoQueryRequest 查询条件
     * @return
     * @throws BusinessException
     */
    @Override
    public IPage<CardOrderInfoVo> pageList(CardOrderInfoQueryRequest cardOrderInfoQueryRequest) throws BusinessException {
        IPage<CardOrderInfo> page = PageUtil.vaildPageParam(cardOrderInfoQueryRequest.getCurrent(), cardOrderInfoQueryRequest.getPageSize());
        String sortField = cardOrderInfoQueryRequest.getSortField();
        String sortOrder = cardOrderInfoQueryRequest.getSortOrder();
        String userName = cardOrderInfoQueryRequest.getUserName();
        String memberCardName = cardOrderInfoQueryRequest.getCardName();
        if (!StrUtil.isBlank(userName)) {
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.like("username", userName);
            User user = (User) userMapper.selectOne(userQueryWrapper);
            cardOrderInfoQueryRequest.setUserName(user.getUsername());
        }

        if (!StrUtil.isBlank(memberCardName)) {
            QueryWrapper<MemberCard> memberCardQueryWrapper = new QueryWrapper<>();
            memberCardQueryWrapper.like("card_name", memberCardName);
            MemberCard memberCard = (MemberCard) memberCardMapper.selectOne(memberCardQueryWrapper);
            cardOrderInfoQueryRequest.setCardName(memberCard.getCardName());
        }
        if (StrUtil.isBlank(sortOrder) || !StrUtil.equalsAny(sortOrder, SortConstant.SORT_ORDER_ASC, SortConstant.SORT_ORDER_DESC)) {
            //默认按升序排序
            sortOrder = SortConstant.SORT_ORDER_ASC;
        }
        cardOrderInfoQueryRequest.setSortField(sortField);
        cardOrderInfoQueryRequest.setSortOrder(sortOrder);

        IPage<CardOrderInfoVo> cardOrderInfoToIPage = cardOrderInfoMapper.selectCardOrderInfoToPage(page, cardOrderInfoQueryRequest);
        IPage<CardOrderInfoVo> cardOrderInfoVoIPage = cardOrderInfoToIPage.convert(item -> {
            CardOrderInfoVo cardOrderInfoVo = new CardOrderInfoVo();
            BeanUtils.copyProperties(item, cardOrderInfoVo);
            return cardOrderInfoVo;
        });

        return cardOrderInfoVoIPage;
    }

    @Override
    public Boolean checkAlipayPayNotify(AlipayPayNotify payNotify) {
        //1 商户需要验证该通知数据中的 out_trade_no 是否为商户系统中创建的订单号
        String outTradeNo = payNotify.getOutTradeNo();
        CardOrderInfo cardOrderInfo = this.getByOrderNo(outTradeNo);
        if (ObjectUtils.isEmpty(cardOrderInfo)) {
            log.error("订单不存在");
            return false;
        }
        //2 判断 total_amount 是否确实为该订单的实际金额（即商户订单创建时的金额）
        Integer totalAmount = payNotify.getTotalAmount().multiply(new BigDecimal(100)).intValue();
        Integer orderTotalFee = cardOrderInfo.getTotalFee();
        if (totalAmount != null && totalAmount.equals(orderTotalFee)) {
            log.error("金额校验失败");
            return false;
        }
        //3 校验通知中的 seller_id（或者 seller_email) 是否为 out_trade_no 这笔单据的对应的操作方
        if (!alipayConfig.getSellerId().equals(payNotify.getSellerId())) {
            log.error("商家pid校验失败");
            return false;
        }

        //4 验证 app_id 是否为该商户本身
        if (!alipayConfig.getAppid().equals(payNotify.getAppId())) {
            log.error("appid校验失败");
            return false;
        }

        //在支付宝的业务通知中，只有交易通知状态为 TRADE_SUCCESS时，
        // 支付宝才会认定为买家付款成功。
        if (!AlipayTradeStatus.TRADE_SUCCESS.getType().equals(payNotify.getTradeStatus())) {
            log.error("支付失败");
            return false;
        }
        return true;
    }

    @Override
    public CardOrderInfo getByOrderNo(String outTradeNo) {
        if (StrUtil.isEmpty(outTradeNo)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<CardOrderInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_no", outTradeNo);
        return this.getOne(wrapper);

    }

    @Override
    public void processAlipayPayNotify(AlipayPayNotify payNotify) {
        //处理重复通知
        CardOrderInfo cardOrderInfo = this.getByOrderNo(payNotify.getOutTradeNo());
        if (ObjectUtils.isEmpty(cardOrderInfo)) {
            throw new RuntimeException("订单不存在");
        }
        if (TradeStateEnum.SUCCESS.getCode().equals(cardOrderInfo.getOrderStatus())) {
            return;
        }
        log.info("receive pay notify,tradeStatus:{}", payNotify.getTradeStatus());
        //处理支付成功的情况
        if (AlipayTradeStatus.TRADE_SUCCESS.getType().equals(payNotify.getTradeStatus()) || AlipayTradeStatus.TRADE_FINISHED.getType().equals(payNotify.getTradeStatus())) {
            cardOrderInfo.setOrderStatus(TradeStateEnum.SUCCESS.getCode());
        } else if (AlipayTradeStatus.TRADE_CLOSED.getType().equals(payNotify.getTradeStatus())) {
            cardOrderInfo.setOrderStatus(TradeStateEnum.CLOSED.getCode());
        }
        //更新订单状态
        this.updateById(cardOrderInfo);
        //记录支付日志
        //String decryptData = JSONObject.toJSONString(payNotify);
        //paymentInfoService.createPaymentInfo(decryptData, PaymentTypeEnum.ALI_PAY);
    }

    @Override
    public void createOrder(Long cardId, Long userId, String orderNo, PaymentTypeEnum paymentTypeEnum) {
        CardOrderInfo cardOrderInfo = new CardOrderInfo();
        MemberCard memberCard = memberCardMapper.selectById(cardId);
        cardOrderInfo.setOrderNo(orderNo)
                .setUserId(userId)
                .setMemberCardId(cardId)
                .setOrderStatus(TradeStateEnum.NOTPAY.getCode())
                .setTotalFee(memberCard.getDiscountPrice().multiply(new BigDecimal(100)).intValue())
                .setPaymentType(paymentTypeEnum.getCode());
        boolean save = this.save(cardOrderInfo);
        if (!save) {
            throw new BusinessException(ErrorCode.SAVE_ERROR);
        }
    }
}




